package com.utils.scrollBar
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.utils.setTimeout;
	
	public class ScrollBar extends MovieClip
	{
		private static const colorMatrixFilter:ColorMatrixFilter = new ColorMatrixFilter([0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0, 0, 0, 1, 1]);
		private static const BAR_DEEP:int = 5;
		
		private var _target:DisplayObject;
		private var _btnUp:UpDownBtn;
		private var _btnDown:UpDownBtn;
		private var _scrollBar:ScrollBtn;
		private var _barBack:ScrollBarBg;
		private var _back:ThisBg;
		private var _maskShape:Shape;
		
		private var _barHeight:int;
		private var _totalValue:int;
		private var _clientX:Number = 0;
		private var _clientY:Number = 0;
		private var _targetX:Number;
		private var _targetY:Number;
		private var _width:int;
		private var _height:int;
		private var _initStatus:Boolean;
		
		public function ScrollBar()
		{
			
		}
		
		/**
		 * 添加目标
		 * @param width 显示宽度
		 * @param height 显示高度
		 * @param target 目标
		 */		
		public function addTarget(target:DisplayObject,width:Number, height:Number):void
		{
			_target = target;
			_targetX = _target.x;
			_targetY = _target.y;
			_height = height;
			_width = width;
			
			if(!_target || !this.parent) return;
			drawBtn();
			setMask(_width,_height);
			registerEventListener();
			upData();
		}
		
		/**添加滚动按钮*/		
		private function drawBtn():void{
			_btnUp = new UpDownBtn();
			this.addChild(_btnUp);
			_btnDown = new UpDownBtn(false);
			this.addChild(_btnDown);
			_btnDown.y = _height - _btnDown.height;
			_barBack = new ScrollBarBg(_btnUp.width-2,_btnDown.y-_btnUp.height-4);
			this.addChild(_barBack);
			_barBack.y = _btnUp.height+2;
			_barBack.x = .5;
			_scrollBar = new ScrollBtn();
			this.addChild(_scrollBar);
			_scrollBar.y = _btnUp.height+2;
			
			_back = new ThisBg(_scrollBar.width,_btnDown.y-_btnUp.y+_btnDown.height);
			this.addChildAt(_back,0);
		}
		
		public function registerEventListener():void
		{
			_btnUp.addEventListener(MouseEvent.CLICK, onUpClickHandler);
			_btnDown.addEventListener(MouseEvent.CLICK, onDownClickHandler);
			_scrollBar.addEventListener(MouseEvent.MOUSE_DOWN, onScrollBarMouseDownHandler);
		}
		
		private function setTotalValue(totalValue:int, currentValue:int = 0, typeStatus:Boolean = false):void
		{
			if(_target) _target.y = _targetY;
			_totalValue = totalValue;
			
			if(!initItemList()) return;
			if(!typeStatus){
				if(currentValue > 0 && _totalValue > _barHeight){
					_scrollBar.y = _btnUp.height + (currentValue / (_totalValue - _barHeight)) * (_barHeight - _btnUp.height - _btnDown.height - _scrollBar.height)
				}
				
				if(_scrollBar.y + _scrollBar.height >= _barHeight - _btnDown.height){
					_scrollBar.y = _barHeight - _btnDown.height - _scrollBar.height;
					if(_initStatus) sendEvent();
				}
				
				if(_totalValue <= _barHeight && _initStatus) sendEvent();
			}else{
				_scrollBar.y = _barHeight - _btnDown.height - _scrollBar.height;
				if(_initStatus) sendEvent();
			}
		}
		
		private function initItemList():Boolean
		{
			_btnUp.y = 0;
			_btnDown.y = _barHeight - _btnDown.height;
			_scrollBar.y = _btnUp.y + _btnUp.height;
			
			if(_totalValue > _barHeight){
				var barHeight:int = (_barHeight - _btnUp.height - _btnDown.height) / _totalValue * (_barHeight - _btnUp.height - _btnDown.height);
				if(barHeight < _btnUp.height) barHeight = _btnUp.height;
				_scrollBar.height = barHeight;
				
				setEnabled(_btnUp,true);
				setEnabled(_btnDown,true);
				setEnabled(_scrollBar,true);
				
				if(!this.hasEventListener(MouseEvent.MOUSE_WHEEL))
				{
					this.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
				}
				
				if(_target && !_target.hasEventListener(MouseEvent.MOUSE_WHEEL)){
					_target.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
				}
				return true;
			}else{
				_scrollBar.height = _btnUp.height;
				_scrollBar.y = _btnUp.y + _btnUp.height;
				
				setEnabled(_btnUp,false);
				setEnabled(_btnDown,false);
				setEnabled(_scrollBar,false);
				
				if(this.hasEventListener(MouseEvent.MOUSE_WHEEL))
				{
					this.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
				}
				
				if(_target && _target.hasEventListener(MouseEvent.MOUSE_WHEEL)){
					_target.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
				}
				return false;
			}
		}
		
		/**
		 * 设置显示范围 
		 * @param width
		 * @param height
		 */		
		public function setMask(width:Number,height:Number):void
		{
			_barHeight = height;
			_barBack.y = _btnUp.y + _btnUp.height;
			
			if(_maskShape == null){
				_maskShape = new Shape();
				
				_target.mask = _maskShape;
				_target.parent.addChild(_maskShape);
			}
			
			_maskShape.graphics.clear();
			_maskShape.graphics.beginFill(0xFFFFFF);
			_maskShape.graphics.drawRect(_targetX,_targetY,width,height);
			_maskShape.graphics.endFill();
			
			_back.height = height;
			_barBack.height = height - _btnUp.height - _btnDown.height;
			_btnUp.y = 0;
			_btnDown.y = height - _btnDown.height;
			_scrollBar.y = _btnUp.y + _btnUp.height;
			
			setTotalValue(_target.height, 0);
		}
		
		/**
		 * 更新滑块
		 * @param isMoveDown 是否滑倒底部
		 */
		public function upData(isMoveDown:Boolean = false):void 
		{
			setTotalValue(_target.height,0,isMoveDown);
			
			if(!_initStatus) _initStatus = true;
		}
		
		private function getScrollSize():Number
		{
			var varHeight:Number = ((_scrollBar.y - _btnUp.height) / (_barHeight - _btnUp.height - _btnDown.height - _scrollBar.height)) * (_totalValue - _barHeight);
			return varHeight;
		}
		
		private function sendEvent():void
		{
			var scrollSize:Number = getScrollSize();
			if(_target) _target.y = _targetY - scrollSize;
		}
		
		private function onScrollBarMouseDownHandler(eventHandler:MouseEvent):void
		{
			_clientX = this.mouseX;
			_clientY = this.mouseY;
			
			if(!stage) return;
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onScrollBarMoveHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, onScrollBarUpHandler);
		}
		
		private function onScrollBarMoveHandler(e:MouseEvent):void
		{
			var subHeight:Number = _clientY - _scrollBar.y;
			_clientY = mouseY;
			
			if(mouseY-subHeight >= _btnUp.height && mouseY-subHeight <= _barHeight-_btnDown.height-_scrollBar.height){
				_scrollBar.y = mouseY - subHeight;
			}else{
				if(mouseY - subHeight < _btnUp.height) _scrollBar.y = _btnUp.y + _btnUp.height;
				if(mouseY - subHeight > _barHeight - _btnDown.height - _scrollBar.height){
					_scrollBar.y = _barHeight - _btnDown.height - _scrollBar.height;
				}
			}
			
			this.sendEvent();
		}
		
		private function onScrollBarUpHandler(e:MouseEvent):void
		{
			if(!stage) return;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,onScrollBarMoveHandler);
			stage.removeEventListener(MouseEvent.MOUSE_UP,onScrollBarUpHandler);
		}
		
		private function onUpClickHandler(eventHandler:MouseEvent):void
		{
			onUpScrollHandler();
		}
		
		private function onDownClickHandler(eventHandler:MouseEvent):void
		{
			onDownScrollHandler();
		}
		
		private function onMouseWheelHandler(e:MouseEvent):void
		{
			e.delta < 0 ? onDownScrollHandler() : onUpScrollHandler();
		}
		
		/**向上运动*/
		private function onUpScrollHandler():void
		{
			if(_scrollBar.y - BAR_DEEP >= _btnUp.height){
				_scrollBar.y = _scrollBar.y - BAR_DEEP;
			}else{
				_scrollBar.y = _btnUp.y + _btnUp.height;
			}
			sendEvent();
		}
		
		/**向下运动*/
		private function onDownScrollHandler():void
		{
			if(_scrollBar.y + _scrollBar.height + BAR_DEEP <= _barHeight - _btnDown.height){
				_scrollBar.y = _scrollBar.y + BAR_DEEP;
			}else{
				_scrollBar.y = _barHeight - _btnDown.height - _scrollBar.height;
			}
			sendEvent();
		}
		
		/**设置按钮显示状态*/		
		private function setEnabled(target:Sprite, status:Boolean):void
		{
			if(!target) return;
			target.mouseChildren = status;
			target.mouseEnabled = status;
			status ? target.filters = [] : target.filters = [colorMatrixFilter];
		}
		
		
		
		
		
		
		public function dispose():void
		{
			unloadEventListener();
		}
		
		/**移除侦听*/		
		public function unloadEventListener():void
		{
			_btnUp.removeEventListener(MouseEvent.CLICK, onUpClickHandler);
			_btnDown.removeEventListener(MouseEvent.CLICK, onDownClickHandler);
			_scrollBar.removeEventListener(MouseEvent.MOUSE_DOWN, onScrollBarMouseDownHandler);
			this.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
			
			if(_target && _target.hasEventListener(MouseEvent.MOUSE_WHEEL)){
				_target.removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelHandler);
			}
		}
		
		
	}
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;

class ThisBg extends Sprite{
	private var _height:int;
	private var _width:int;
	public function ThisBg(width:int=15,height:int = 30){
		_width = width;
		_height = height;
		drawBg();
	}
	
	private function drawBg():void{
		this.graphics.clear();
		this.graphics.beginFill(0xFF0000,0);
		this.graphics.drawRoundRect(0,0,_width,_height,1,1);
		this.graphics.endFill();
		this.filters = [new GlowFilter(0,1,3,3,3,1)];
	}
	
	
}

class ScrollBtn extends Sprite{
	private var _height:int;
	public function ScrollBtn(height:int = 30){
		this.buttonMode = true;
		_height = height;
		drawBg();
	}
	
	private function drawBg():void{
		this.graphics.clear();
		this.graphics.lineStyle(1,0,1,true);
		this.graphics.beginFill(0x4B3A2E,1);
		this.graphics.drawRoundRect(0,0,15,_height,1,1);
		this.graphics.endFill();
	}
	
	
}

class ScrollBarBg extends Sprite{
	private var _height:int;
	private var _width:int;
	public function ScrollBarBg(width:int = 0,heigth:int = 0){
		_width = width;
		_height = heigth;
		drawBg();
	}
	
	private function drawBg():void{
		this.graphics.clear();
		this.graphics.beginFill(0x1B1B1B,1);
		this.graphics.drawRect(0,0,_width,_height);
		this.graphics.endFill();
		drawLine();
	}
	
	private function drawLine():void{
		this.graphics.lineStyle(2,0x645D57);
		this.graphics.moveTo(2,2);
		this.graphics.lineTo(_width-2,2);
		this.graphics.lineTo(_width-2,_height-2);
		this.graphics.lineTo(2,_height-2);
		this.graphics.lineTo(2,2);
		this.graphics.endFill();
	}
}


class UpDownBtn extends Sprite{
	
	private var _isUp:Boolean;
	public function UpDownBtn(isUp:Boolean = true){
		_isUp = isUp; 
		this.buttonMode = true;
		this.addEventListener(Event.ADDED_TO_STAGE,onAddedToStageHandler);
	}
	
	private function onAddedToStageHandler(e:Event):void{
		this.removeEventListener(Event.ADDED_TO_STAGE,onAddedToStageHandler);
		this.addEventListener(MouseEvent.MOUSE_DOWN,onClickHandler);
		this.stage.addEventListener(MouseEvent.MOUSE_UP,onClickHandler);
		drawBg();
	}
	
	private function onClickHandler(e:MouseEvent):void{
		e.type == MouseEvent.MOUSE_DOWN ? drawBg(0x4B3A2E,0x6A4A31) : drawBg();
	}
	
	private function drawBg(bgColor:uint = 0x4B3A2E,trigonColor:uint = 0xC1905F):void{
		this.graphics.clear();
		this.graphics.lineStyle(1,0,1,true);
		this.graphics.beginFill(bgColor);
		this.graphics.drawRoundRect(0,0,15,15,1,1);
		this.graphics.endFill();
		_isUp ? drawTrigon(trigonColor) : drawTrigon(trigonColor,-5)
	}
	
	private function drawTrigon(trigonColor:uint = 0xC1905F,offsetY:int = 5):void{
		this.graphics.beginFill(trigonColor);
		this.graphics.moveTo(0,7 + offsetY);
		this.graphics.lineTo(15,7 + offsetY);
		this.graphics.lineTo(7.5,7 - offsetY);
		this.graphics.lineTo(0,7 + offsetY);
		this.graphics.endFill();
	}
}